package com.parsec.sb.spring.async;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;

@RestController
@RequiredArgsConstructor( onConstructor = @__(@Autowired) )
public class AsyncController {

    private final AsyncTask asyncTask;

    @RequestMapping("/async/run")
    public String runTaskByAsync() {
        System.out.println("Start runTask ...");
        long start = System.currentTimeMillis();

        asyncTask.runTask1();
        asyncTask.runTask2();

        long end = System.currentTimeMillis();
        System.out.println("Over runTask, Run Time: " + (end-start) + "ms");

        return "Async Success";
    }

    @RequestMapping("/async/future")
    public String runTaskAsync3() {

        Future<String> future = null;
        List<Future<String>> futureList = new ArrayList<>();

        long start = System.currentTimeMillis();
        // 创建异步任务
        future = asyncTask.runTask("task 1", 11);
        futureList.add(future);

        future = asyncTask.runTask("task 2", 18);
        futureList.add(future);

        future = asyncTask.runTask("task 3", 17);
        futureList.add(future);

        // 异步任务执行结果查询
        if(!futureList.isEmpty()) {

            // 阻塞等待所有异步任务完成
            boolean isAllDone = false;
            while(!isAllDone) {
                isAllDone = true;
                for(Future<String> futureElement : futureList) {
                    // 该异步任务未完成
                    if( !futureElement.isDone() ) {
                        isAllDone = false;
                        break;
                    }
                }
            }
            long end = System.currentTimeMillis();
            // 取出各异步任务执行结果
            System.out.println("========= 异步任务执行结果 =========");
            for(Future<String> futureElement : futureList) {
                try {
                    String result = futureElement.get();
                    System.out.println(result);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.out.println("========= 当前线程耗时 =========");
            System.out.println( (end-start)/1000 + " s" );
        }
        return "Good Test";
    }
}
